#include "stream_tools.h"
#include "mbv2.h"
#include "utils.h"
#include "mbv2_para.h"
#include "avgpool.h"

int main()
{
	int32_t error_cnt;
	#ifdef HLS_CSIM
	std::string input_path = "../../../../../blob/input.afm";
	std::string b1n1_c1_path = "../../../../../blob/b1n1_c1.afm";
	#else
	std::string input_path = "../blob/input.afm";
	std::string conv0_path = "../blob/conv0.afm";
	std::string b1n1_c1_path = "../blob/b1n1_c1.afm";
	std::string b1n1_c2_path = "../blob/b1n1_c2.afm";
	std::string b1n1_c3_path = "../blob/b1n1_c3.afm";
	std::string b2n1_c3_path = "../blob/b2n1_c3.afm";
	std::string b2n2_c3_path = "../blob/b2n2_c3.afm";
	std::string b2n1_b2n2_path = "../blob/b2n1_b2n2.afm";
	std::string b3n1_c3_path = "../blob/b3n1_c3.afm";
	std::string b3n2_c3_path = "../blob/b3n2_c3.afm";
	std::string b3n3_c3_path = "../blob/b3n3_c3.afm";
	std::string b3n1_b3n2_path = "../blob/b3n1_b3n2.afm";
	std::string b3n1_b3n2_b3n3_path = "../blob/b3n1_b3n2_b3n3.afm";
	std::string b4n1_c3_path = "../blob/b4n1_c3.afm";
	std::string b4n2_c3_path = "../blob/b4n2_c3.afm";
	std::string b4n3_c3_path = "../blob/b4n3_c3.afm";
	std::string b4n4_c3_path = "../blob/b4n4_c3.afm";
	std::string b4n1_b4n2_b4n3_b4n4_path = "../blob/b4n1_b4n2_b4n3_b4n4.afm";
	std::string b5n1_c3_path = "../blob/b5n1_c3.afm";
	std::string b5n2_c3_path = "../blob/b5n2_c3.afm";
	std::string b5n3_c3_path = "../blob/b5n3_c3.afm";
	std::string b6n1_c3_path = "../blob/b6n1_c3.afm";
	std::string b6n2_c3_path = "../blob/b6n2_c3.afm";
	std::string b6n3_c3_path = "../blob/b6n3_c3.afm";
	std::string b7n1_c3_path = "../blob/b7n1_c3.afm";
	std::string conv8_path = "../blob/conv8.afm";
	std::string avgpool_path = "../blob/avgpool.cfm";
	#endif

	data_stream<BIT_ACTV> s_input("s_input");
	load_ifm<N_BATCH, HIGHT1*WIDTH1*b1n1_c3_NOCH>(s_input, "../blob/b1n1_c3.afm");
	std::cout << "s_input size: " << (int32_t)s_input.size() << std::endl;

	data_stream<BIT_IO> s_input_e("s_input_e");
	expandWidth<BIT_ACTV, BIT_IO, HIGHT1*WIDTH1*b1n1_c3_NOCH*N_BATCH>(s_input, s_input_e);
	std::cout << "s_input_e size: " << (int32_t)s_input_e.size() << std::endl;

	axiu_stream<BIT_IO> s_output("s_output");
	mobilenet_v2(s_input_e, s_output);
	std::cout << "s_output size(): " << s_output.size() << std::endl;

	error_cnt = check_cfm<N_BATCH, b2n2_c3_NOCH*HIGHT2*WIDTH2*N_BATCH>(s_output, "../blob/b2n1_b2n2.fm");

	if(error_cnt > 0)
	{
		std::cout << "Test Failed! " << error_cnt << " errors" << std::endl;
		return 1;
	}
	else
	{
		std::cout << "Test Passed! " << std::endl;
		return 0;
	}
}